#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QModbusClient>
#include <QModbusDataUnit>
#include <QPushButton>
#include <QFile>

#define INISET_FILE             "./setting.ini"
#define PCBA_HELP               "ChlorinatorMV1.2_PCBA.pdf"
#define MACHINE_HELP            "ChlorinatorMV1.2_MACHINE.pdf"
#define SOFT_VER                "1.0"
#define CHECK_DEV_TIMEOUT       6
#define CONSUMER_START_ADDR     0x0
#define FACTORY_MODBUS_ADDR     8
#define FACTORY_START_ADDR      0x800
#define GAS_SW_ADDR             (CONSUMER_START_ADDR + 20)
#define CONTROL_SIGNAL_ADDR     (FACTORY_START_ADDR + 1)
#define FACTORY_BEEP_START      (FACTORY_START_ADDR + 4)
#define FACTORY_BEEP_END        (FACTORY_START_ADDR + 5)
#define TEST_TIMER_INTERVAL     200
#define TEST_COUNT_DOWN_START   (60*1000/TEST_TIMER_INTERVAL)
#define CFG_START_ADDR          FACTORY_START_ADDR+1
#define CONTROL_SIGNAL_WRITE_INTERVAL   5
// 数据长度定义
#define IR_LEN                  18      // input register长度
#define GAS_SW_LEN              1
#define ICID_LEN                6
#define FACTORY_DI_LEN          10
#define CONTROL_SIGNAL_LEN      3

#define TEST_PCBA               0
#define TEST_MACHINE            1

#define TEST_ITEM_NUM           19
#define TEST_ITEM_KEY_NUM       5

#define HEARTBEAT_TIMEOUT       3

// 测试结果位置，可屏蔽
#define PH_RESULT_POS           0
#define ORP_RESULT_POS          1
#define WATER_TEMP_RESULT_POS   2

QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow;
}
QT_END_NAMESPACE


enum test_style
{
    STYLE_DEFAULT,
    STYLE_PASS,
    STYLE_FAIL,
};

enum connect_state_machine
{
    CONNECT_START,
    READ_UID,
    CALC_PASSWORD,
    WRITE_PASSWORD,
    ENTER_FACTORY,
};

enum test_state_machine
{
    TEST_START,
    WRITE_CFG,
    READ_INFO,
    READ_IR,
    READ_GAS_SW_IR,
    WRITE_CONTROL_SIGNAL,
    READ_FACTORY_DI,
    TEST_PASS,
    TEST_TIMEOUT,
    TEST_COM_TIMEOUT,
    TEST_WAIT_DEV_DISCONNECT,
    TEST_WAIT_DEV_CONNECT,

};

struct input_register_struct
{
    uint16_t orp;
    uint16_t ph;
    uint16_t tds;
    uint16_t waterTemp;
    uint16_t devTemp;
    uint16_t power;
    uint16_t qulity;
    uint16_t electrolyticSpec;
    uint16_t sj;
    uint16_t si;
    uint16_t sv;
    uint16_t i;
    uint16_t u;
    uint16_t softMain;
    uint16_t softSub;
    uint16_t productType;
    uint16_t productCfg;
    uint16_t electrolyticLife;
    uint16_t gasSw;
};

struct test_result
{
    uint32_t pH:1;
    uint32_t orp:1;
    uint32_t waterTemp:1;
    uint32_t devTemp:1;
    uint32_t sj:1;
    uint32_t u:1;
    uint32_t i:1;
    uint32_t gas:1;
    uint32_t flow:1;
    uint32_t WIFI:1;
    uint32_t RTC:1;
    uint32_t dryPoint:1;
    uint32_t acidMotor:1;
    uint32_t beep:1;
    uint32_t keyPower:1;
    uint32_t keyMinus:1;
    uint32_t keySet:1;
    uint32_t keyPlus:1;
    uint32_t keyBoost:1;

};

union test_result_t
{
    test_result bit;
    uint32_t word;
};

union input_register_t
{
    input_register_struct ir;
    uint16_t ar[IR_LEN];
};

struct factory_di
{
    bool keyPower;
    bool keyMinus;
    bool keySet;
    bool keyPlus;
    bool keyBoost;
    bool flowSwitch;
    bool wifiTest;
    bool rtcTest;
    bool motorTest;
    bool beepTest;
};

union factory_di_t
{
    struct factory_di fd;
    bool ar[FACTORY_DI_LEN];
};

struct factory_coil_t
{
    bool factoryMode;
    bool dryPoint;
    bool RC;
    bool SR;
    bool beepStart;
    bool beepEnd;
};

struct test_t
{
    bool isInFactoryMode = false;
    bool writeResult = false;
    bool uidReadResult = false;
    connect_state_machine connectSM = CONNECT_START;
    test_state_machine  testSM = TEST_START;
    uint32_t testCountDownTick;
    uint16_t password;
    uint32_t crc32Icid;
    uint16_t uid[6]={0};
    uint16_t controlSignalWrite = 0;
    uint16_t controlSignalWriteTick = 0;
    bool isInfoRead = false;
    int controlStep = 0;
    test_result_t itemResult,lastResult;
    bool testResult;
    uint32_t heartBeatDisconnectCount;
    // modbus数据
    input_register_t ir;
    factory_di_t fd;
    factory_coil_t fc;


};

struct value_range
{
    uint16_t std;
    uint16_t range;
};

struct value_range_t
{
    value_range pH;
    value_range orp;
    value_range waterTemp;
    value_range devTemp;
    value_range sj;
    value_range u;
    value_range i;
    value_range gas;
};



class MainWindow : public QMainWindow
{
    Q_OBJECT


public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private slots:
    void on_pb_openPort_clicked();

    void on_cb_deviceCfg_currentIndexChanged(int index);

    void on_cb_electrolytic_currentIndexChanged(int index);

    void on_cb_testType_currentIndexChanged(int index);

    void on_cb_writeCfg_checkStateChanged(const Qt::CheckState &arg1);

    void on_pb_beep_clicked();

    void on_pb_acidMotor_clicked();

    void on_cb_orpExist_checkStateChanged(const Qt::CheckState &arg1);

    void on_cb_pHExist_checkStateChanged(const Qt::CheckState &arg1);

    void on_dsp_waterTempStd_valueChanged(double arg1);

    void on_dsp_devTempStd_valueChanged(double arg1);

    void on_pb_help_clicked();

private:
    Ui::MainWindow *ui;
    void Fill_SerialPort();
    bool Read_Settings(int type);
    void Updata_Settings_Display(void);
    void Calc_PassWord(void);
    void Display_Info(void);
    void Control_Dev_Enter_FactoryMode(void);
    void Write_FactoryTestStart();
    void Write_FactoryTestStop();
    void Dev_Test_Process(void);
    void Test_Main(void);
    void Read_UID();
    void On_UID_Ready(void);
    void Read_IR();
    void On_IR_Ready();
    void Read_GasSw();
    void On_GasSw_Ready();
    void Read_Factory_DI();
    void On_Factory_DI_Ready();
    void Write_PassWord();
    void Write_Cfg();
    void Write_FactoryMode();
    void Write_Control_Signal(void);
    void On_Write_Reply();
    void PushButton_Style_Set(QPushButton* b,enum test_style style);
    void StyleSheet_Set(test_style style,QWidget* w);
    void Test_Reset(void);
    bool Test_Control_Signal(void);
    void Test_Control_Signal_PCBA(void);
    void Test_Control_Signal_Machine(void);
    void Test_Result_Check(void);
    void Test_Result_Display(void);
    void Test_Result_Testing_Display(void);
    void Test_Log_Init();
    void Test_Log_Write();


// 变量定义
private:
    QModbusClient *modbusDevice = nullptr;
    QTimer* m_serialPortTimer;
    QTimer* m_testTimer;
    QFile* m_logFile;
    bool m_writeCfg = false;
    int m_testType = TEST_PCBA;
    int m_electrolytic  = 0;
    uint16_t m_deviceCfg;
    test_t m_test;
    value_range_t m_valueRange;
    QString m_uid;
    QString m_devId;
    bool m_orpExist = true;
    bool m_pHExist = true;
    uint32_t m_resultMask = 0x7FFFF;


};
#endif // MAINWINDOW_H
